package 反射.取两个对象值不同的属性;

import lombok.SneakyThrows;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * 通过属性进行比较
 */
public class FieldEquator extends AbstractEquator {

    private FieldEquator() {
    }

    public static Equator builder() {
        return new FieldEquator();
    }

    @SneakyThrows
    @Override
    public List<DiffField> getDiffFields(Object oldObj, Object newObj) {
        List<DiffField> diffFields = new ArrayList<>();
        if (oldObj == null && newObj == null || oldObj == newObj) {
            return diffFields;
        } else if (!isSimpleField(oldObj, newObj)) {
            Object obj = oldObj == null ? newObj : oldObj;
            Class<?> clazz = obj.getClass();
            Field[] fields = clazz.getDeclaredFields();  //获取所有属性对象集合

            for (int i = 0; i < fields.length; i++) {
                Field field = fields[i];
                String fieldName = field.getName();
                field.setAccessible(true);  //允许访问私有属性

                if (field.isAnnotationPresent(FieldAvoid.class)) {
                    continue;
                }

                //获取值
                Object oldVal = oldObj == null ? null : field.get(oldObj);
                Object newVal = newObj == null ? null : field.get(newObj);

                if (isDiff(fieldName, oldVal, newVal) || field.isAnnotationPresent(FieldReturn.class)) {
                    String fieldAlias = null;
                    if (field.isAnnotationPresent(FieldAlias.class)) {  //属性是否标注有该注解
                        FieldAlias annotation = field.getAnnotation(FieldAlias.class);
                        fieldAlias = annotation.value();
                    }
                    DiffField curDiff = new DiffField(fieldName, fieldAlias, oldVal, newVal);
                    diffFields.add(curDiff);
                }
            }
        }
        return diffFields;
    }

}
